
#include <d3d9.h>
#include "d3d_texture_manager.h"
#include "clientinterfaces.h"
#include <iltclient.h>
#include "ltclientshell.h"
#include "pageinfogetter.hpp"

void d3d_texture_manager::load_textures_from_page(const std::string& page) {
    using namespace Utility ;
    property_keys_type keys ;
    page_info_getter::Instance().get_keys(page, keys) ;
    for_each(keys.begin(), keys.end(), boost::bind(&d3d_texture_manager::add_a_texture_from_page,
                                                   this, page, _1)) ;
}

void d3d_texture_manager::add_a_texture_from_page(const std::string& page,
                                                  const std::string& name) {
    using namespace Utility ;
    std::string file_name = page_info_getter::Instance().
        get<std::string>(page, name, "file_name") ;
    int type = page_info_getter::Instance().
        get(page, name, "type", -1) ;
    add_texture(name, file_name, type) ;
}

bool d3d_texture_manager::has_texture(const std::string& name)  const {
    return m_textures.count(name) == 1 ;
}

bool d3d_texture_manager::add_texture(const std::string& name,
                                      const std::string& file_name,
                                      int type) {
    if(has_texture(name)) return false ;
    IDirect3DDevice9* device = g_pLTClient->GetD3DWrapper()
        ->GetDevice() ;
    if(!device) return false ;
    if(type == 0) {
        IDirect3DCubeTexture9* cube = 0 ;
        D3DXCreateCubeTextureFromFile(device, file_name.c_str(), &cube) ;
        if(!cube) return false ;
        m_textures[name] = boost::make_tuple(cube, file_name, type) ;
        return true ;
    }
    return false ;
}


d3d_texture_manager::~d3d_texture_manager() {
    release_all_textures() ;
    m_textures.clear() ;
}

void d3d_texture_manager::release_all_textures() {
    texture_group_type::iterator it(m_textures.begin()) ;
    for( ; it != m_textures.end() ; ++it) {
        boost::any tex ;
        std::string name ;
        int type ;
        boost::tie(tex, name, type) = (*it).second ;
        switch(type) {
        case 0: {
            IDirect3DCubeTexture9* t = boost::any_cast<IDirect3DCubeTexture9*>(tex) ;
            t->Release() ;
        } break;
        }
    }
}

void d3d_texture_manager::recreate_textures() {
    IDirect3DDevice9* device = g_pLTClient->GetD3DWrapper()
        ->GetDevice() ;
    texture_group_type::iterator it(m_textures.begin()) ;
    if(!device) return ;
    for( ; it != m_textures.end() ; ++it) {
        boost::any tex ;
        std::string name ;
        int type ;
        boost::tie(tex, name, type) = (*it).second ;
        switch(type) {
        case 0: {
            IDirect3DCubeTexture9* t = boost::any_cast<IDirect3DCubeTexture9*>(tex) ;
            t->Release() ;
            D3DXCreateCubeTextureFromFile(device, name.c_str(), &t) ;
            boost::get<TITE_TEXTURE>((*it).second) = t ;
        } break;
        }
    }
}

void d3d_texture_manager::remove_texture(const std::string& name) {
    if(!has_texture(name)) return ;
    boost::any tex ;
    std::string fname ;
    int type ;
    boost::tie(tex, fname, type) = m_textures[name] ;
    switch(type) {
    case 0: {
        IDirect3DCubeTexture9* t = boost::any_cast<IDirect3DCubeTexture9*>(tex) ;
        t->Release() ;
    }break ;
    }
    m_textures.erase(name) ;
}

    
